home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
MPW_TOOL
/
TOOLS
/
TOOLS_WI
/
ICON_8
/
ICONX_FO
/
LSCAN.C
< prev
next >
Wrap
Text File
|
1990-03-02
|
4KB
|
198 lines
/*
* File: lscan.c
* Contents: bscan, escan
*/
#include "::h:config.h"
#include "::h:rt.h"
#include "rproto.h"
#ifdef PreProcess
/* include(../M4/lib.m4) /* */
/* */
#endif /* PreProcess */
/*
* bscan - set &subject and &pos upon entry to a scanning expression.
*
* Arguments are:
* Arg0 - new value for &subject
* Arg1 - saved value of &subject
* Arg2 - saved value of &pos
*
* A variable pointing to the saved &subject and &pos is returned to be
* used by escan.
*/
LibDcl(bscan,2,"?")
{
char sbuf[MaxCvtLen];
int rc;
struct pf_marker *cur_pfp;
#if MACINTOSH
#if MPW
/* #pragma unused(nargs) */
#endif /* MPW */
#endif /* MACINTOSH */
/*
* Convert the new value for &subject to a string.
*/
if (DeRef(Arg0) == Error)
RunErr(0, NULL);
switch (cvstr(&Arg0, sbuf)) {
case Cvt:
/*
* The new value for &subject wasn't a string. Allocate the
* new value and fall through.
*/
if (strreq(StrLen(Arg0)) == Error)
RunErr(0, NULL);
StrLoc(Arg0) = alcstr(StrLoc(Arg0), StrLen(Arg0));
case NoCvt:
/*
* Establish a new &subject value and set &pos to 1.
*/
k_subject = Arg0;
k_pos = 1;
break;
default:
RunErr(103, &Arg0);
}
/* If the saved scanning environment belongs to the current procedure
* call, put a reference to it in the procedure frame.
*/
if (pfp->pf_scan == NULL)
pfp->pf_scan = &Arg1;
cur_pfp = pfp;
/*
* Suspend with a variable pointing to the saved &subject and &pos.
*/
ArgType(0) = D_Var;
VarLoc(Arg0) = &Arg1;
rc = interp(G_Csusp,cargp);
if (pfp != cur_pfp)
return rc;
/*
* Leaving scanning environment. Restore the old &subject and &pos values.
*/
k_subject = Arg1;
k_pos = IntVal(Arg2);
if (pfp->pf_scan == &Arg1)
pfp->pf_scan = NULL;
if (rc == A_Resumption)
return A_Failure;
else
return rc;
}
/*
* escan - restore &subject and &pos at the end of a scanning expression.
*
* Arguments:
* Arg0 - variable pointing to old values of &subject and &pos
* Arg1 - result of the scanning expression
*
* The two arguments are reversed, so that the result of the scanning
* expression becomes the result of escan. This result is dereferenced
* if it refers to &subject or &pos. Then the saved values of &subject
* and &pos are exchanged with the current ones.
*
* Escan suspends once it has restored the old &subject; on failure
* the new &subject and &pos are "unrestored", and the failure is
* propagated into the using clause.
*/
LibDcl(escan,1,"escan")
{
struct descrip tmp;
int rc;
struct pf_marker *cur_pfp;
#if MACINTOSH
#if MPW
/* #pragma unused(nargs) */
#endif /* MPW */
#endif /* MACINTOSH */
/*
* Copy the result of the scanning expression into Arg0, which will
* be the result of the scan.
*/
tmp = Arg0;
Arg0 = Arg1;
Arg1 = tmp;
/*
* If the result of the scanning expression is &subject or &pos,
* it is dereferenced.
*/
if (((char *)BlkLoc(Arg0) == (char *)&tvky_sub) ||
((char *)BlkLoc(Arg0) == (char *)&tvky_pos))
if (DeRef(Arg0) == Error)
RunErr(0, NULL);
/*
* Swap new and old values of &subject
*/
tmp = k_subject;
k_subject = *VarLoc(Arg1);
*VarLoc(Arg1) = tmp;
/*
* Swap new and old values of &pos
*/
tmp = *(VarLoc(Arg1) + 1);
IntVal(*(VarLoc(Arg1) + 1)) = k_pos;
k_pos = IntVal(tmp);
/*
* If we are returning to the scanning environment of the current
* procedure call, indicate that it is no longed in a saved state.
*/
if (pfp->pf_scan == VarLoc(Arg1))
pfp->pf_scan = NULL;
cur_pfp = pfp;
/*
* Suspend the value of the scanning expression.
*/
rc = interp(G_Csusp,cargp);
if (pfp != cur_pfp)
return rc;
/*
* Re-entering scanning environment, exchange the values of &subject
* and &pos again
*/
tmp = k_subject;
k_subject = *VarLoc(Arg1);
*VarLoc(Arg1) = tmp;
tmp = *(VarLoc(Arg1) + 1);
IntVal(*(VarLoc(Arg1) +1)) = k_pos;
k_pos = IntVal(tmp);
if (pfp->pf_scan == NULL)
pfp->pf_scan = VarLoc(Arg1);
if (rc == A_Resumption)
return A_Failure;
else
return rc;
}